﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JPSOFTWARE.BON.Modelos;

namespace JPSOFTWARE.BON.Regra
{
    public class RnBase
    {
        public void ValidarCnpjCpf(string valor)
        {
            bool retorno = false;
            string _valor = valor;
            _valor = LimparMascara(_valor);
            if (_valor.Length == 11)
            {
                retorno = ValidaCPF(_valor);
            }
            else if (_valor.Length == 14)
            {
                retorno = ValidaCNPJ(_valor);
            }

            if (retorno == false)
            {
                throw new Exception(Mensagens.MSG_002);
            }
        }

        public bool ValidaCPF(string vrCPF)
        {
            string valor = vrCPF.Replace(".", "");
            valor = valor.Replace("-", "");


            if (valor.Length != 11)
                return false;


            bool igual = true;
            for (int i = 1; i < 11 && igual; i++)
                if (valor[i] != valor[0])
                    igual = false;


            if (igual || valor == "12345678909")
                return false;


            int[] numeros = new int[11];


            for (int i = 0; i < 11; i++)
                numeros[i] = int.Parse(
                  valor[i].ToString());


            int soma = 0;
            for (int i = 0; i < 9; i++)
                soma += (10 - i) * numeros[i];


            int resultado = soma % 11;


            if (resultado == 1 || resultado == 0)
            {
                if (numeros[9] != 0)
                    return false;
            }
            else if (numeros[9] != 11 - resultado)
                return false;


            soma = 0;
            for (int i = 0; i < 10; i++)
                soma += (11 - i) * numeros[i];


            resultado = soma % 11;


            if (resultado == 1 || resultado == 0)
            {
                if (numeros[10] != 0)
                    return false;
            }
            else
                if (numeros[10] != 11 - resultado)
                    return false;


            return true;
        }

        /// <summary>
        /// Realiza a validação do CNPJ
        /// </summary>

        public bool ValidaCNPJ(string cnpj)
        {
            if (cnpj.Equals("00000000000000") ||
                cnpj.Equals("11111111111111") ||
                cnpj.Equals("22222222222222") ||
                cnpj.Equals("33333333333333") ||
                cnpj.Equals("44444444444444") ||
                cnpj.Equals("55555555555555") ||
                cnpj.Equals("66666666666666") ||
                cnpj.Equals("77777777777777") ||
                cnpj.Equals("88888888888888") ||
                cnpj.Equals("99999999999999"))                
                return false;

            int[] multiplicador1 = new int[12] { 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };
            int[] multiplicador2 = new int[13] { 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };
            int soma;
            int resto;
            string digito;
            string tempCnpj;
            cnpj = cnpj.Trim();
            cnpj = cnpj.Replace(".", "").Replace("-", "").Replace("/", "");
            if (cnpj.Length != 14)
                return false;
            tempCnpj = cnpj.Substring(0, 12);
            soma = 0;
            for (int i = 0; i < 12; i++)
                soma += int.Parse(tempCnpj[i].ToString()) * multiplicador1[i];
            resto = (soma % 11);
            if (resto < 2)
                resto = 0;
            else
                resto = 11 - resto;
            digito = resto.ToString();
            tempCnpj = tempCnpj + digito;
            soma = 0;
            for (int i = 0; i < 13; i++)
                soma += int.Parse(tempCnpj[i].ToString()) * multiplicador2[i];
            resto = (soma % 11);
            if (resto < 2)
                resto = 0;
            else
                resto = 11 - resto;
            digito = digito + resto.ToString();
            return cnpj.EndsWith(digito);
        }
        

        public string LimparMascara(string valor)
        {
            if (valor == null)
            {
                return null;
            }

            valor = valor.Replace("(", "");
            valor = valor.Replace(")", "");
            valor = valor.Replace("-", "");
            valor = valor.Replace("_", "");
            valor = valor.Replace(" ", "");
            valor = valor.Replace(".", "");
            valor = valor.Replace("/", "");

            return valor;
        }

        public static string FormataString(string mascara, string valor)
        {
            if (valor == null || valor.Length == 0)
            {
                return "";
            }

            string novoValor = string.Empty;
            int posicao = 0;

            for (int i = 0; mascara.Length > i; i++)
            {
                if (mascara[i] == '#')
                {
                    if (valor.Length > posicao)
                    {
                        novoValor = novoValor + valor[posicao];
                        posicao++;
                    }
                    else
                        break;
                }
                else
                {
                    if (valor.Length > posicao)
                        novoValor = novoValor + mascara[i];
                    else
                        break;
                }
            }
            return novoValor;
        }

        public void ValidarString(string valor, int tamanho, bool obrigatorio = true)
        {
            if (obrigatorio)
            {
                if (valor == null || valor.Length == 0)
                {
                    throw new Exception(Mensagens.MSG_001);
                }
                else if (valor.Length > tamanho)
                {
                    throw new Exception(Mensagens.MSG_002);
                }
            }
            else
            {
                if (valor != null && valor.Length > tamanho)
                {
                    throw new Exception(Mensagens.MSG_002);
                }
            }
        }

        public void ValidarId(int valor)
        {
            if (valor < 1)
            {
                throw new Exception(Mensagens.MSG_002);
            }
        }

        public void ValidarInt(int valor)
        {
            if (valor < 0)
            {
                throw new Exception(Mensagens.MSG_002);
            }
        }

        public void ValidarInt(int? valor)
        {
            if (valor != null)
            {
                if (valor < 0)
                {
                    throw new Exception(Mensagens.MSG_002);
                }
            }
        }

        public void ValidarData(DateTime valor)
        {
            // O Tipo DateTime não aceita valor nulo, logo, seu valor nulo é 01/01/0001.
            // Para o DateTime receber valor nulo, deve ser declarado como DateTime?.
            if (valor.Day == 1 && valor.Month == 1 && valor.Year == 1)
            {
                throw new Exception(Mensagens.MSG_001);
            }
        }

        public void ValidarData(DateTime? valor)
        {
            if (valor != null)
            {
                if (valor.Value.Day == 1 && valor.Value.Month == 1 && valor.Value.Year == 1)
                {
                    throw new Exception(Mensagens.MSG_001);
                }
            }
        }

        public void ValidarHora(TimeSpan? valor)
        {
            if (valor != null)
            {
                if (valor.Value.TotalSeconds < 0)
                {
                    throw new Exception(Mensagens.MSG_001);
                }
            }
        }

        /// <summary>
        /// Converte o valor de string para DateTime.
        /// Caso o valor seja inválido, ou anterior a 1753, a função retorna a data 01/01/1800.
        /// Isso é feito pois o campo DateTime no SQL Server não aceita datas anteriores a 1753.
        /// </summary>
        /// <param name="valor">Data no formato string. Ex: "01/01/2000"</param>
        /// <param name="dataFinal">
        ///     É informado true quando é esperado uma data final. 
        ///     Nessa data é acrescentado 23h59m59s pegar todos os resultados daquele dia.
        /// </param>
        /// <returns>Retorna a data, com valor mínimo de 01/01/1800.</returns>
        public DateTime AjustaData(string valor, bool dataFinal = false)
        {
            if (valor.Length > 10)
            {
                valor = valor.Substring(0, 10);
            }

            DateTime dt;
            DateTime.TryParse(valor, out dt);

            if (dt.Year < 1800)
            {
                return DateTime.MinValue.AddYears(1799);
            }

            if (dataFinal)
            {
                if (dt.Year > 1800)
                {
                    dt = dt.AddHours(23);
                    dt = dt.AddMinutes(59);
                    dt = dt.AddSeconds(59);
                    return dt.AddMilliseconds(999);
                }
            }

            return dt;
        }

        //retira os caracteres definidos como especiais, obrigatório informar se quer retirar os espaços vazios antes de depois da variável
        public string LimparCaracterEspecial(string str, bool espacoVazio)
        {
            if (espacoVazio)
            {
                str.Trim();
                str.Replace("(", "");
                str.Replace(")", "");
                str.Replace(",", "");
                str.Replace("'", "");
                str.Replace("-", "");
                str.Replace("/", "");
                str.Replace(".", "");
                str.Replace("?", "");
                str.Replace("!", "");
            }
            else
            {
                str.Trim();
                str.Replace("(", "");
                str.Replace(")", "");
                str.Replace(",", "");
                str.Replace("'", "");
                str.Replace("-", "");
                str.Replace("/", "");
                str.Replace(".", "");
                str.Replace("?", "");
                str.Replace("!", "");
                str.Replace(" ", "");
            }
            return str;
        }

        //se o campo for obrigatório, deve receber essa validação
        public bool ValidarCampoObrigatorio(string str)
        {
            bool retorno = false;

            if (string.IsNullOrEmpty(str))
                return retorno;
            else
            {
                retorno = true;
                return retorno;
            }
        }

        //validar e-mail 
        public bool ValidarEmail(string eMail)
        {
            bool retorno = false;
            int indexArr = eMail.IndexOf("@");

            if (indexArr > -1)
            {
                int indexDot = eMail.IndexOf(".", indexArr);
                if ((indexDot > -1) && ((eMail.Length - 1) > indexDot))
                {
                    retorno = true;
                }
            }
            else
            {
                throw new Exception(Mensagens.MSG_002);
            }
            return retorno;
        }
    }
}
